package vin.pth.example.authrization.provider;

import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import vin.pth.authorization.exception.AuthorizationException;
import vin.pth.authorization.provider.AuthorizationProvider;
import vin.pth.base.pojo.Authentication;
import vin.pth.base.pojo.UserDetails;
import vin.pth.base.service.UserDetailsService;
import vin.pth.example.authrization.token.SmsCodeToken;

/**
 * @author Cocoon
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class SmsCodeProvider implements AuthorizationProvider {

  private final static String DEFAULT_SMS_CODE = "123456";
  private final static String PHONE_KEY = "username";
  private final static String SMS_CODE_KEY = "smsCode";
  private final UserDetailsService userDetailsService;


  /**
   * 认证.
   *
   * @param param 认证参数.
   * @return 认证结果
   * @throws AuthorizationException 鉴权异常
   */
  @Override
  public Authentication authenticate(Map<String, Object> param) throws AuthorizationException {
    String phone = "";
    String smsCode = "";
    if (param.get(PHONE_KEY) != null) {
      phone = param.get(PHONE_KEY) + "";
    }
    if (param.get(SMS_CODE_KEY) != null) {
      smsCode = param.get(SMS_CODE_KEY) + "";
    }
    if (!smsCode.equals(DEFAULT_SMS_CODE)) {
      throw new AuthorizationException(401202, "验证码错误，请重新输入");
    }

    log.warn("短信验证码认证逻辑，默认直接通过");
    UserDetails userDetails = userDetailsService.loadUserByUsername(phone);
    if (userDetails == null) {
      throw new AuthorizationException(401404, "用户不存在");
    }
    return new SmsCodeToken(phone, smsCode, userDetails);
  }

  /**
   * 是否支持该认证对象.
   *
   * @param param 认证参数.
   * @return 认证结果
   */
  @Override
  public boolean supports(Map<String, Object> param) {
    String phone = "";
    String smsCode = "";
    if (param.get(PHONE_KEY) != null) {
      phone = param.get(PHONE_KEY) + "";
    }
    if (param.get(SMS_CODE_KEY) != null) {
      smsCode = param.get(SMS_CODE_KEY) + "";
    }
    return StringUtils.hasText(phone) && StringUtils.hasText(smsCode);
  }
}
